package cn.mymall.util;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URL;
import java.util.*;

public class BeanUtil {

	public static List<Integer> getIdList(String ids){
		List<Integer> idList = new ArrayList<Integer>();
		if(StringUtils.isBlank(ids)){
			return idList;
		}
		String[] ss = ids.split(",");
		for(String s : ss){
			try {
				idList.add(Integer.valueOf(s));
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		return idList;
	}
	public static List<Long> getIdList2(String ids){
		List<Long> idList = new ArrayList<Long>();
		if(StringUtils.isBlank(ids)){
			return idList;
		}
		String[] ss = ids.split(",");
		for(String s : ss){
			try {
				idList.add(Long.valueOf(s));
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		return idList;
	}

	/**
	 *
	 * @param destList  被赋值数据
	 * @param origList 原始数据
	 */
	public static void copyListProperties(List origList, List destList, Class destCls) {
		for(Object orig : origList) {
			try {
				Object dest = destCls.newInstance();
				PropertyUtils.copyProperties(dest, orig);
				destList.add(dest);
			} catch (Exception e) {
				// ignore
				e.printStackTrace();
			}
		}
	}
	/**
	 *
	 * @param origList 原始数据
	 */
	public static List copyListProperties(List origList, Class destCls) {
		List distList = new ArrayList();
		for(Object orig : origList) {
			try {
				Object dest = destCls.newInstance();
				PropertyUtils.copyProperties(dest, orig);
				distList.add(dest);
			} catch (Exception e) {
				// ignore
				e.printStackTrace();
			}
		}
		return distList;
	}

	public static void copyProperties(Object dest, Object orig) {
		try {
			PropertyUtils.copyProperties(dest, orig);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static Object get(Object object, String property) {
		try {
			return PropertyUtils.getProperty(object, property);
		} catch (IllegalAccessException e) {
		} catch (InvocationTargetException e) {
		} catch (NoSuchMethodException e) {
		} catch (Exception e) {
		}
		return null;
	}
	public static void set(Object object, String property, Object newproperty) {
		try {
			PropertyUtils.setProperty(object, property, newproperty);
		} catch (IllegalAccessException e) {
		} catch (InvocationTargetException e) {
		} catch (Exception e) {
		}
	}
	public static Map beanListToMap(final Collection beanList, String keyproperty) {
		Map result = new HashMap();
		for (Object bean : beanList) {
			try {
				Object key = PropertyUtils.getNestedProperty(bean, keyproperty);
				if (key != null)
					result.put(key, bean);
			} catch (Exception e) {
			}
		}
		return result;
	}

	public static <T> List<T> getBeanPropertyList(final Collection beanList, String propertyname, boolean unique) {
		List<T> result = new ArrayList<T>();
		for (Object bean : beanList) {
			try {
				T pv = (T) PropertyUtils.getProperty(bean, propertyname);
				if (pv != null && (!unique || !result.contains(pv)))
					result.add(pv);
			} catch (Exception e) {
			}
		}
		return result;
	}

	public static List<Long> getLongIdList(String ids){
		List<Long> idList = new ArrayList<Long>();
		if(StringUtils.isBlank(ids)){
			return idList;
		}
		String[] ss = ids.split(",");
		for(String s : ss){
			try {
				idList.add(Long.valueOf(s));
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		return idList;
	}
	public static <T> List<T> getSubList(List<T> list, int from, int maxnum) {
		if (list == null || list.size() <= from)
			return new ArrayList<T>();
		return new ArrayList(list.subList(from, Math.min(from + maxnum, list.size())));
	}

	public static Map getBeanMap(final Object bean) {
		return getBeanMap(bean, true);
	}

	public static Map getBeanMap(final Object bean, boolean nested) {
		return getBeanMap(bean, nested, false);
	}

	public static Map<String, Object> getBeanMap(final Object bean, boolean nested, boolean ignoreNull) {
		if (bean == null)
			return null;
		if(isSimpleProperty(bean.getClass())){
			throw new IllegalArgumentException("bean can't be simple!");
		}

		Map beanMap = null;
		try {
			if (bean instanceof Map) {
				beanMap = new LinkedHashMap((Map) bean);
			} else {
				beanMap = PropertyUtils.describe(bean);
			}
			Object pv = null;
			for (Object key : new ArrayList(beanMap.keySet())) {
				pv = beanMap.get(key);
				if (pv == null) {
					if (ignoreNull)
						beanMap.remove(key);
				} else if (!isSimpleProperty(pv.getClass())) {// 非Primitive类型
					if (!nested) {
						beanMap.remove(key);
					} else {
						if (pv instanceof Collection)
							beanMap.put(key, getBeanMapList((Collection) pv, false));
						else if (pv.getClass().isArray())
							beanMap.put(key, getBeanMapList(Arrays.asList((Object[]) pv), false));
						else
							beanMap.put(key, getBeanMap(pv, false));
					}
				}
			}
			beanMap.remove("class");
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return beanMap;
	}
	public static boolean isSimpleProperty(Class<?> clazz) {
		if(clazz == null){
			throw new IllegalArgumentException("Class must not be null");
		}
		return isSimpleValueType(clazz) || (clazz.isArray() && isSimpleValueType(clazz.getComponentType()));
	}

	/**
	 * 获取Bean数组的Primitive属性的值
	 *
	 * @param beanList
	 * @return
	 */
	public static List getBeanMapList(final Collection beanList, boolean nested) {
		List result = new ArrayList<Map>();
		for (Object bean : beanList) {
			if (bean == null || isSimpleProperty(bean.getClass()))
				result.add(bean);
			else
				result.add(getBeanMap(bean, nested));
		}
		return result;
	}

	public static boolean isSimpleValueType(Class<?> clazz) {
		return ClassUtil.isPrimitiveOrWrapper(clazz) || clazz.isEnum() || CharSequence.class.isAssignableFrom(clazz) || Number.class.isAssignableFrom(clazz) || Date.class.isAssignableFrom(clazz)
				|| clazz.equals(URI.class) || clazz.equals(URL.class) || clazz.equals(Locale.class) || clazz.equals(Class.class);
	}

	public static List<Map> getBeanMapList(final Collection beanList, String... properties) {
		List<Map> result = new ArrayList<Map>();
		if(beanList == null) return result;
		Iterator it = beanList.iterator();
		Object bean = null;
		while (it.hasNext()) {
			bean = it.next();
			Map beanMap = new HashMap();
			boolean hasProperty = false;
			for (String property : properties) {
				try {
					Object pv = null;
					String keyname = property;
					if (property.indexOf(".") > 0) {// 复合属性
						pv = PropertyUtils.getNestedProperty(bean, property);
						keyname = keyname.replace('.', '_');
					} else {
						pv = PropertyUtils.getProperty(bean, property);
					}
					if (pv != null) {
						hasProperty = true;
						beanMap.put(keyname, pv);
					}
				} catch (Exception e) {
				}
			}
			if (hasProperty)
				result.add(beanMap);
		}
		return result;
	}

	public static Map getBeanMapWithKey(final Object bean, String... propertyList) {
		return getBeanMapWithKey(bean, false, propertyList);
	}

	public static Map getBeanMapWithKey(final Object bean, boolean nested, String... keys) {
		return getBeanMapWithKey(bean, nested, false, keys);
	}

	public static Map getBeanMapWithKey(final Object bean, boolean nested, boolean ignoreNull, String... keys) {
		if (keys == null || keys.length == 0)
			return getBeanMap(bean, nested, ignoreNull);
		Map result = new HashMap();
		Object pv = null;
		for (String key : keys) {
			try {
				pv = PropertyUtils.getNestedProperty(bean, key);
			} catch (Exception e) {
			}
			if (pv == null) {
				if (ignoreNull)
					continue;
				else
					result.put(key, null);
			} else if (!isSimpleProperty(pv.getClass())) {// 非Primitive类型
				if (nested) {
					if (pv instanceof Collection)
						result.put(key, getBeanMapList((Collection) pv, false));
					else
						result.put(key, getBeanMap(pv, false));
				}
			} else {
				result.put(key, pv);
			}
		}
		return result;
	}

	/**
	 * 处理列表或map里所有的日期格式。
	 * 找到map中key为addtime或created的值，改成预设的日期格式
	 */
	public static void convertAddTime(Object object){
		if(object==null)
			return;
		if(object instanceof List){
			List l = (List) object;
			for (Object item : l) {
				convertAddTime(item);
			}
			return;
		}
		if(object instanceof Map){
			Map m = (Map) object;
			for (Object key : m.keySet()) {
				Object val = m.get(key);
				if(val instanceof List)
					convertAddTime(val);
				else{
					if("addtime".equals(key)
							||"created".equals(key)){
						if(val==null) return;
						Date date = DateUtil.parseDate(val.toString());
						if(date==null)
							date = DateUtil.parseDate(val.toString(),"yyyy-MM-dd HH:mm:ss");
						if(date!=null){
							m.put(key, DateUtil.getTimeDesc2(date));
						}
//						convertAddTime(val);
					}
				}

			}
			return;
		}
	}

	public static Map groupBeanList(final Collection beanList, String property) {
		return groupBeanList(beanList, property, null);
	}

	/**
	 * 根据property的值将beanList分组, null作为单独一组，key 为nullKey
	 * @param beanList
	 * @param property
	 * @param nullKey
	 * @return
	 */
	public static Map groupBeanList(final Collection beanList, String property, Object nullKey) {
		Map<Object, List> result = new LinkedHashMap<Object, List>();
		for (Object bean : beanList) {
			try {
				Object keyvalue = PropertyUtils.getNestedProperty(bean, property);
				if (keyvalue == null)
					keyvalue = nullKey;
				if (keyvalue != null) {
					List tmpList = result.get(keyvalue);
					if (tmpList == null) {
						tmpList = new ArrayList();
						result.put(keyvalue, tmpList);
					}
					tmpList.add(bean);
				}
			} catch (Exception e) {
			}
		}
		return result;
	}

}
